#include <stdafx.h>
#include "ScriptEditorTabWidget.h"
#include "ScriptEditorWidget.h"
#include "ScriptLogOutput.h"
#include <LitString.h>
#include <LitEditorFileDialog.h>
#include <LitEditorInstance.h>

namespace Lit
{
	namespace Editor
	{
		ScriptTabWidget::ScriptTabWidget( QWidget * parent )
			: QTabWidget(parent), mBaseName("new_script"), mExt("as")
		{
		}
		ScriptTabWidget::~ScriptTabWidget( ){}
		
		void ScriptTabWidget::setEditorInstance( InstancePtr logger ){ mInstance = logger; }
		InstancePtr ScriptTabWidget::getEditorInstance() const{ return mInstance; }

		void ScriptTabWidget::setExtension( const std::string &ext )
		{
			mExt = ext;
		}
		const std::string &ScriptTabWidget::getExtension() const
		{
			return mExt;
		}
		bool ScriptTabWidget::checkUnsavedScripts() const
		{
			for( auto i=pages.begin(); i!=pages.end(); i++ )
				if( i->second->isModified() ) return true;
			return false;
		}
		void ScriptTabWidget::saveAllUnsavedScripts()
		{
			for( auto i=pages.begin(); i!=pages.end(); i++ )
				if( i->second->isModified() ) i->second->saveScript();
		}
		void ScriptTabWidget::closeScript(ScriptEditorWidgetPtr s)
		{
			if( !s ) return;
			if( s->isModified() )
			{
				int ret = QMessageBox::question( this, "Modifications Detected", "Do you want to save '"+QString(s->getPath().fileName().c_str())+"' ?", QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel );
				if( ret == QMessageBox::Cancel ) return;
				else if( ret == QMessageBox::Yes ) s->saveScript();
			}
				
			auto i=findScript( s->getPath().str() );
			if( i==pages.end() ) return;
			pages.erase(i);
			removeTab( s->getId() );
			if( s ) s.destroy();
		}
		ScriptEditorWidgetPtr ScriptTabWidget::currentScript()
		{
			QWidget * curWidget=currentWidget();
			for( auto i=pages.begin(); i!=pages.end(); i++ )
				if( (QWidget*)i->second == curWidget )
					return i->second;
			return NULL;
		}
		bool ScriptTabWidget::hasScript( const std::string &name ) const{ return pages.find(name) != pages.end(); }
		void ScriptTabWidget::removeScript( const std::string &name )
		{
			std::map<std::string, ScriptEditorWidget*>::iterator i=pages.find(name);
			if( i == pages.end() )
				return;
			removeTab( i->second->getId() );
			pages.erase( i );
		}
		void ScriptTabWidget::setBaseName( const std::string &base ){ mBaseName = base; }
		const std::string &ScriptTabWidget::getBaseName() const{ return mBaseName; }
		
		std::string ScriptTabWidget::nextName() const
		{
			std::string name = mBaseName;
			size_t id = 0;
			while( hasScript(name) )
			{
				name = String(mBaseName)("_")(id).str(); id++;
			}
			return name;
		}
		ScriptEditorWidgetPtr ScriptTabWidget::addScript( const std::string &p )
		{
			FilePath path(p.empty()?FileDialog::getOpenFileName( NULL, "Add Script", ScriptUserPath(), "All AngelScript Files (*."+mExt+");;" ):FilePath(p));
			if( !path.exists() ) return NULL;
			std::string name = path.fileName(false);
			std::string full = path.dirName() + "/" + name + "."+mExt;

			if( hasScript( name ) ) throw std::runtime_error("script '"+name+"."+mExt+"' already exists");
			if( !Lit::FileSystem::exists( full ) ) throw std::runtime_error("cannot open script stream '"+full+"'");

			ScriptEditorWidget * editor = (pages[full] = new ScriptEditorWidget( mInstance, this ));
			editor->setText( FileStream( path.str(), Stream::TextRead ).readAll() );
			editor->setPath( full );
			editor->setModified(false);

			pages[full] = editor;
			addTab( editor, QString(name.c_str())+"."+mExt.c_str() );

			return editor;
		}
		ScriptEditorWidgetPtr ScriptTabWidget::createScript(const std::string &name_, const std::string &content){
			std::string name = name_.empty()?nextName():FilePath(name_).fileName(false);
			std::string path = ScriptUserPath() + "/" + name + "."+mExt;
			pages[path] = new ScriptEditorWidget( mInstance, this );
			ScriptEditorWidget * editor = pages[path];
			editor->setText( content );
			editor->setModified( true );
			editor->setPath( path );
			addTab( editor, QString(name.c_str())+"."+mExt.c_str() );
			return editor;
		}

		
		void ScriptTabWidget::modifiedStateChanged(ScriptEditorWidget * widget, bool state)
		{
			if( state ) setTabText( widget->getId(), QString( widget->getName().c_str() ) + " *" );
			else setTabText( widget->getId(), QString( widget->getName().c_str() ) );
		}
	};
};